package com.alinesno.cloud.operation.cmdb.web.bean;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.jpa.domain.Specification;

/**
 * 分页数据
 * 
 * @author LuoAnDong
 * @since 2018年8月16日 上午8:59:44
 */
public class JqDatatablesPageBean {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private int start; // 开始条数
	private int length; // 每页显示
	private int recordsFiltered;
	private Object data;
	private int draw;
	private int recordsTotal;
	private Map<String, Object> condition = new ConcurrentHashMap<String, Object>();

	public int getStart() {
		return start;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public int getLength() {
		return length;
	}

	public void setLength(int length) {
		this.length = length;
	}

	public int getRecordsFiltered() {
		return recordsFiltered;
	}

	public void setRecordsFiltered(int recordsFiltered) {
		this.recordsFiltered = recordsFiltered;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public int getDraw() {
		return draw;
	}

	public void setDraw(int draw) {
		this.draw = draw;
	}

	public int getRecordsTotal() {
		return recordsTotal;
	}

	public void setRecordsTotal(int recordsTotal) {
		this.recordsTotal = recordsTotal;
	}

	public Map<String, Object> getCondition() {
		return condition;
	}

	public void setCondition(Map<String, Object> condition) {
		this.condition = condition;
	}

	/**
	 * 从request中获得参数Map，并返回可读的Map
	 * 
	 * @param request
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "serial" })
	public <T> Specification buildFilter(T t, HttpServletRequest request) {
		Specification p = new Specification<T>() {

			@Override
			public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicates = new ArrayList<Predicate>();

				if (condition != null) {

					Iterator<Map.Entry<String, Object>> iterator = getCondition().entrySet().iterator();
					while (iterator.hasNext()) {
						Map.Entry<String, Object> me = iterator.next();
						String[] keys = me.getKey().trim().split("\\|");
						Object value = me.getValue();

						logger.debug("key = {} , value = {}", keys[0], value);

						if (keys.length == 1) {
							predicates.add(cb.equal(root.get(keys[0]), me.getValue()));
						} else if (keys.length >= 2) {
							String conditionKey = keys[1];
							String conditionVal = me.getValue()+"" ;

							switch (conditionKey) {
								case "like": predicates.add(cb.like(root.get(keys[0]),"%"+conditionVal+"%")) ;break;
								case "notLike": predicates.add(cb.notLike(root.get(keys[0]),"%"+conditionVal+"%")) ;break;
								case "likeLeft": predicates.add(cb.like(root.get(keys[0]),"%"+conditionVal)) ;break;
								case "likeRight": predicates.add(cb.like(root.get(keys[0]),conditionVal+"%")) ;break;
								case "le": predicates.add(cb.le(root.get(keys[0]),Double.parseDouble(conditionVal))) ;break;
								case "lt": predicates.add(cb.lt(root.get(keys[0]),Double.parseDouble(conditionVal))) ;break;
								case "ge": predicates.add(cb.ge(root.get(keys[0]),Double.parseDouble(conditionVal))) ;break;
								case "gt": predicates.add(cb.gt(root.get(keys[0]),Double.parseDouble(conditionVal))) ;break;
								default:predicates.add(cb.equal(root.<Object>get(keys[0]), me.getValue()));break;
							}

						}
					}
				}

				return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
			}
		};

		return p;
	}
}
